﻿using Kingdee.BOS.BusinessEntity.BusinessFlow;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.EntityElement;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.Orm;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace DzInfo.SS.ServicePlugIn
{
    [Description("暂估应收反审核时，自动删除对应差额调整单，如果还存在其他下游单据则不允许反审核"), HotUpdate]
    public class UnAudit : AbstractOperationServicePlugIn
    {
        /// <summary>
        /// 加载所有列
        /// </summary>
        /// <param name="e"></param>
        public override void OnPreparePropertys(PreparePropertysEventArgs e)
        {
            base.OnPreparePropertys(e);
            FormMetadata meta = MetaDataServiceHelper.GetFormMetaData(this.Context, this.BusinessInfo.GetForm().Id);
            var fieldKeyList = meta.BusinessInfo.GetBosFields().Select(x => x.Field.Key).ToList();
            for (int i = 0; i < fieldKeyList.Count; i++)
            {
                e.FieldKeys.Add(fieldKeyList[i]);
            }
        }
        /// <summary>
        /// 得到目标单据内码集合
        /// </summary>
        /// <param name="bInfo"></param>
        /// <param name="entity"></param>
        /// <param name="entityIds"></param>
        /// <returns></returns>
        private object[] GetTargetBillPkId(BusinessInfo bInfo, string entitykey, List<long> entityIds)
        {
            List<object> lstPks = new List<object>();
            var entity = bInfo.GetEntity(entitykey);
            var pkKey = string.Concat(entity.Key, "_", entity.EntryPkFieldName);
            var filter = string.Format(" {0} IN ({1}) ", pkKey, string.Join(",", entityIds));
            var queryParam = new QueryBuilderParemeter();
            queryParam.FormId = bInfo.GetForm().Id;
            queryParam.SelectItems.Add(new SelectorItemInfo(bInfo.GetForm().PkFieldName));
            queryParam.SelectItems.Add(new SelectorItemInfo(pkKey));
            queryParam.FilterClauseWihtKey = filter;
            var objs = QueryServiceHelper.GetDynamicObjectCollection(this.Context, queryParam);
            foreach (var obj in objs)
            {
                lstPks.Add(obj[0].ToString());
            }
            return lstPks.ToArray();
        }
        /// <summary>
        /// 加载元数据
        /// </summary>
        /// <param name="formId"></param>
        /// <returns></returns>
        private BusinessInfo LoadBusinessInfo(string formId)
        {
            //MetaDataService metaService = new MetaDataService();
            FormMetadata metadata = FormMetaDataCache.GetCachedFormMetaData(this.Context, formId);
            BusinessInfo sBusinessInfo = metadata.BusinessInfo;
            return sBusinessInfo;
        }
        /// <summary>
        /// 删除下游单据
        /// </summary>
        /// <param name="lstEntityPkIds"></param>
        /// <param name="parentEntity"></param>
        private void DeleteTrackDown(List<DynamicObject> objs)
        {
            //关联实体
            var linkEntity = this.BusinessInfo.GetForm().LinkSet.LinkEntitys[0];
            //关联主实体
            Entity parentEntity = this.BusinessInfo.GetEntity(linkEntity.ParentEntityKey);
            //关联数据包集合
            List<long> lstEntityPkIds = new List<long>();
            foreach (var data in objs)
            {
                var entityObjs = parentEntity.DynamicProperty.GetValue(data) as DynamicObjectCollection;
                foreach (var entityObj in entityObjs)
                {
                    lstEntityPkIds.Add(Int64.Parse(entityObj[0].ToString()));
                }
            }
            if (lstEntityPkIds.Count > 0)
            {
                var tableDefine = BusinessFlowServiceHelper.LoadTableDefine(this.Context, this.BusinessInfo.GetForm().Id, parentEntity.Key);
                Dictionary<TableDefine, List<long>> dicTrackEntity = new Dictionary<TableDefine, List<long>>();
                dicTrackEntity[tableDefine] = lstEntityPkIds;
                var trackNodes = BusinessFlowDataServiceHelper.GetTrackNodes(this.Context, dicTrackEntity, true);
                var delNodes = trackNodes.Where(w => w.Key.Equals("OCOD_t_Cust_Entry100058"));
                OperateOption option = OperateOption.Create();
                option.SetIgnoreWarning(true);
                foreach (var trackNode in delNodes)
                {
                    var targetTableDefine = BusinessFlowServiceHelper.LoadTableDefine(this.Context, trackNode.Key);
                    //得到下游单据元数据
                    var targetBusinessInfo = this.LoadBusinessInfo(targetTableDefine.FormId);
                    //需要删除的下游单据内码集合
                    var arrPks = this.GetTargetBillPkId(targetBusinessInfo, targetTableDefine.EntityKey, trackNode.Value);
                    //调用删除操作
                    var deleteResult = BusinessDataServiceHelper.Delete(this.Context, targetBusinessInfo, arrPks, option);
                    //删除结果不成功，一般下游部分单据存在已审核状态的数据，则调用反审核，再次调用删除
                    if (deleteResult.IsSuccess == false)
                    {
                        var failPkValues = deleteResult.ValidationErrors.Select(x => x.BillPKID).ToArray();
                        BusinessDataServiceHelper.UnAudit(this.Context, targetBusinessInfo, failPkValues, option);
                        BusinessDataServiceHelper.Delete(this.Context, targetBusinessInfo, failPkValues, option);
                    }
                }
            }
        }
        /// <summary>
        /// 事务内删除，下游单据
        /// </summary>
        /// <param name="e"></param>
        public override void EndOperationTransaction(EndOperationTransactionArgs e)
        {
            base.EndOperationTransaction(e);
            //需要处理的数据包
            //var objs = this.OperationResult.OperateResult.Where(x => x.SuccessStatus).Select(x => x.DataEntity).ToList();
            var objs = e.DataEntitys.ToList();
            //删除下游单据
            this.DeleteTrackDown(objs);
        }
        /// <summary>
        /// 事务内删除，则需要先删除验证，如果是事务外删除则不需要加此事件
        /// </summary>
        /// <param name="e"></param>
        public override void OnAddValidators(AddValidatorsEventArgs e)
        {
            base.OnAddValidators(e);
            // 获取立账类型
            int accountType = GetAccountType(e.DataEntities);
            if (accountType == 2)
            {
                var isDel = CheckRows(e.DataEntities);
                if (isDel)
                {
                    e.Validators.RemoveAll(x => x.GetType().ToString().EndsWith("ConditionValidator"));
                }
            }
        }
        private bool CheckRows(DynamicObject[] objs)
        {
            //关联实体
            var linkEntity = this.BusinessInfo.GetForm().LinkSet.LinkEntitys[0];
            //关联主实体
            Entity parentEntity = this.BusinessInfo.GetEntity(linkEntity.ParentEntityKey);
            //关联数据包集合
            List<long> lstEntityPkIds = new List<long>();
            foreach (var data in objs)
            {
                var entityObjs = parentEntity.DynamicProperty.GetValue(data) as DynamicObjectCollection;
                foreach (var entityObj in entityObjs)
                {
                    lstEntityPkIds.Add(Int64.Parse(entityObj[0].ToString()));
                }
            }
            if (lstEntityPkIds.Count > 0)
            {
                var tableDefine = BusinessFlowServiceHelper.LoadTableDefine(this.Context, this.BusinessInfo.GetForm().Id, parentEntity.Key);
                Dictionary<TableDefine, List<long>> dicTrackEntity = new Dictionary<TableDefine, List<long>>();
                dicTrackEntity[tableDefine] = lstEntityPkIds;
                var trackNodes = BusinessFlowDataServiceHelper.GetTrackNodes(this.Context, dicTrackEntity, true);
                var delNodes = trackNodes.Where(w => w.Key.Equals("OCOD_t_Cust_Entry100058"));
                if (trackNodes.Count == delNodes.Count() && delNodes.Count() == 1)
                {
                    return true;
                }
            }
            return false;
        }
        /// <summary>
        /// 获取立账类型
        /// </summary>
        private int GetAccountType(DynamicObject[] dataEntities)
        {
            return dataEntities.Select(d => Convert.ToInt32(d["FSETACCOUNTTYPE"])).FirstOrDefault();
        }
    }
}
